<!--
参考：
https://blog.csdn.net/u012468376/article/details/73350998
https://www.cnblogs.com/haonanZhang/p/9396087.html
-->
<template>
  <div>
    <canvas id="canvas_dom_id" :width="width" :height="height"></canvas>
  </div>
</template>

<script>
  export default {
    name: "VueCanvas",
    props: {
      width: {
        type: Number,
        default: 200
      },
      height: {
        type: Number,
        default: 100
      },
      value: {
        type: String,
        require: true
      },
      backgroundColorMin: {
        type: Number,
        default: 180
      },
      backgroundColorMax: {
        type: Number,
        default: 240
      },
      fontSizeMin: {
        type: Number,
        default: 20
      },
      fontSizeMax: {
        type: Number,
        default: 35
      },
      fontColorMin: {
        type: Number,
        default: 50
      },
      fontColorMax: {
        type: Number,
        default: 160
      },
      fontRotateMin: {
        type: Number,
        default: -45
      },
      fontRotateMax: {
        type: Number,
        default: 45
      },
      lineColorMin: {
        type: Number,
        default: 40
      },
      lineColorMax: {
        type: Number,
        default: 100
      },
      lineCount: {
        type: Number,
        default: 3
      },
      dotColorMin: {
        type: Number,
        default: 0
      },
      dotColorMax: {
        type: Number,
        default: 255
      },
      dotCount: {
        type: Number,
        default: 30
      }

    },
    methods: {
      random(min, max) {
        return Math.floor(Math.random() * (max - min + 1) + min);
      },
      randomColor(min, max) {
        return 'rgb(' + this.random(min, max) + ',' + this.random(min, max) + ',' + this.random(min, max) + ')';
      },
      randomFont(min, max) {
        return this.random(min, max) + 'px SimHei';
      },
      canvas() {
        return document.getElementById('canvas_dom_id');
      },
      context() {
        return this.canvas().getContext('2d');
      },
      draw() {
        let context = this.context();
        // 背景颜色
        context.fillStyle = this.randomColor(this.backgroundColorMin, this.backgroundColorMax);
        // 矩形
        context.fillRect(0, 0, this.width, this.height);
        // 验证码
        this.drawText(context);
        // 干扰线
        this.drawLine(context);
        // 干扰点
        this.drawArc(context);
      },
      drawText(context) {
        let value = this.value;
        let xSpan = this.width / value.length;
        for (let i = 0; i < value.length; i++) {
          // 字体背景色
          context.fillStyle = this.randomColor(this.fontColorMin, this.fontColorMax);
          // 字体大小
          context.font = this.randomFont(this.fontSizeMin, this.fontSizeMax);
          // 字体X轴
          let x = xSpan * i + 10;
          // 字体Y轴
          let y = this.random(this.fontSizeMin, this.height - 5);
          // 字体旋转度
          let rotate = this.random(this.fontRotateMin, this.fontRotateMax);
          // 绘制
          context.save();
          context.translate(x, y);
          context.rotate(rotate * Math.PI / 180);
          context.fillText(value[i], 0, 0);
          context.restore();
        }
      },
      drawLine(context) {
        for (let i = 0; i < this.lineCount; i++) {
          context.fillStyle = this.randomColor(this.lineColorMin, this.lineColorMax);
          context.beginPath();
          context.moveTo(this.random(0, this.width), this.random(0, this.height));
          context.lineTo(this.random(0, this.width), this.random(0, this.height));
          context.stroke();
        }
      },
      drawArc(context) {
        for (let i = 0; i < this.dotCount; i++) {
          context.fillStyle = this.randomColor(this.dotColorMin, this.dotColorMax);
          context.beginPath();
          context.arc(this.random(0, this.width), this.random(0, this.height), 1, 0, 2 * Math.PI);
          context.fill();
        }
      }
    },
    watch: {
      value() {
        this.draw();
      }
    },
    mounted() {
      this.draw();
    }
  }
</script>

<style scoped>

</style>
